package org.monitoringtools.manager;

import static org.monitoringtools.util.AssertUtil.assertNotNull;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.monitoringtools.elements.Monitor;
import org.monitoringtools.util.AssertUtil;

public class MonitorManager {

    private final Map<String, Monitor> monitor;

    private final String[] monitorIds;

    private Date monitoringStart = new Date();

    public MonitorManager(String... monitorIds) {
        assertNotNull((Object) (this.monitorIds = monitorIds));
        this.monitor = initChannels();
    }

    public synchronized long failure(String id) {
        return validateAndGetMonitorById(id).failure();
    }

    public Monitor getMonitor(String id) {
        return this.monitor.get(id);
    }

    public Date getMonitoringStart() {
        return monitoringStart;
    }

    public synchronized void logFailure(String id) {
        validateAndGetMonitorById(id).logFailure();
    }

    public synchronized void logSuccess(String id) {
        validateAndGetMonitorById(id).logSuccess();
    }

    public synchronized void reset() {
        this.monitoringStart = new Date();

        for (String id : this.monitorIds)
            this.monitor.get(id).reset();
    }

    public synchronized long success(String id) {
        return validateAndGetMonitorById(id).success();
    }

    public synchronized long total(String id) {
        return validateAndGetMonitorById(id).total();
    }

    private synchronized Monitor validateAndGetMonitorById(String id) {
        AssertUtil.assertFieldNotNull(id, this.monitor.get(id), "No monitor found");
        return this.monitor.get(id);
    }

    private synchronized Map<String, Monitor> initChannels() {
        final Map<String, Monitor> map = new HashMap<String, Monitor>();
        for (String id : this.monitorIds)
            map.put(id, new Monitor(id));

        return map;
    }
}